﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Text;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.ComponentModel;
using Lswweb.Domain;

namespace Lswweb.Controls
{
    public delegate IList DataSourceHandler(string args);

    public class CheckBoxGridView : Control
    {
        /// <summary>
        /// args为父级节点的ValueField，如为根及则是默认值string.Empty
        /// </summary>
        public event DataSourceHandler GridViewDataSourceHandler;

        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            Page.ClientScript.RegisterHiddenField(HiddenInputId, SelectValues);
            Page.ClientScript.RegisterStartupScript(typeof(CheckBoxGridView), "CheckBoxClick", RenderScript(), true);
        }

        protected override void Render(HtmlTextWriter writer)
        {
            if (!string.IsNullOrEmpty(Style))
                writer.AddAttribute(HtmlTextWriterAttribute.Style, Style);
            if (!string.IsNullOrEmpty(Css))
                writer.AddAttribute(HtmlTextWriterAttribute.Class, Css);
            writer.AddAttribute(HtmlTextWriterAttribute.Id, this.ClientID);
            writer.AddStyleAttribute("clear", "both");
            writer.RenderBeginTag(HtmlTextWriterTag.Ul);

            if (GridViewDataSourceHandler == null)
                throw new Exception("必须设置GridViewDataSourceHandler");
            RenderItems(writer, GridViewDataSourceHandler(string.Empty));

            writer.RenderEndTag();
        }

        private void RenderItems(HtmlTextWriter writer,IList listSource)
        {
            foreach (object obj in listSource)
            {

                string value = Globals.GetPropertyValue(obj, ValueField).ToString();
                IList childListSource = GridViewDataSourceHandler(value);
                if (childListSource.Count > 0)
                {
                    writer.RenderBeginTag(HtmlTextWriterTag.Li);

                    if (!string.IsNullOrEmpty(ItemHeadStyle))
                        writer.AddAttribute(HtmlTextWriterAttribute.Style, ItemHeadStyle);
                    if (!string.IsNullOrEmpty(ItemHeadCss))
                        writer.AddAttribute(HtmlTextWriterAttribute.Class, ItemHeadCss);
                    writer.AddStyleAttribute("clear", "both");
                    writer.RenderBeginTag(HtmlTextWriterTag.Div);
                    RenderCheckBox(writer, obj);
                    writer.RenderEndTag();

                    if (!string.IsNullOrEmpty(ItemContentStyle))
                        writer.AddAttribute(HtmlTextWriterAttribute.Style, ItemContentStyle);
                    if (!string.IsNullOrEmpty(ItemHeadCss))
                        writer.AddAttribute(HtmlTextWriterAttribute.Class, ItemHeadCss);
                    writer.AddStyleAttribute("clear", "both");
                    writer.AddAttribute(HtmlTextWriterAttribute.Id, GetChildItemContentId(value));
                    writer.RenderBeginTag(HtmlTextWriterTag.Ul);
                    RenderItems(writer, childListSource);
                    writer.RenderEndTag();

                    writer.RenderEndTag();
                }
                else
                {
                    writer.AddStyleAttribute("float","left");
                    if (!string.IsNullOrEmpty(ItemStyle))
                        writer.AddAttribute(HtmlTextWriterAttribute.Style, ItemStyle);
                    if (!string.IsNullOrEmpty(ItemContentCss))
                        writer.AddAttribute(HtmlTextWriterAttribute.Class, ItemContentCss);
                    writer.RenderBeginTag(HtmlTextWriterTag.Li);
                    RenderCheckBox(writer, obj);

                    writer.RenderEndTag();
                }

                
            }
        }

        private void RenderCheckBox(HtmlTextWriter writer,object dataItem)
        {
            string value=Globals.GetPropertyValue(dataItem,ValueField).ToString();
            string path= Globals.GetPropertyValue(dataItem,PathField).ToString();

            writer.AddAttribute(HtmlTextWriterAttribute.Onclick, "CheckBoxClick(this,'" + GetChildItemContentId(value) + "','" + this.ClientID + "','" + HiddenInputId + "','" + path + "');");
            writer.AddAttribute(HtmlTextWriterAttribute.Type, "checkbox");
            writer.AddAttribute(HtmlTextWriterAttribute.Value,value);
            Regex regex = new Regex("(" + SelectValues.ToLower() + ")$");
            if (!string.IsNullOrEmpty(SelectValues) && regex.Match(value.ToLower()).Success)
                writer.AddAttribute(HtmlTextWriterAttribute.Checked,"true");
            writer.RenderBeginTag(HtmlTextWriterTag.Input);
            writer.RenderEndTag();
            writer.RenderBeginTag(HtmlTextWriterTag.Span);
            writer.Write(Globals.GetPropertyValue(dataItem, TextField).ToString());
            writer.RenderEndTag();
        }

        private string RenderScript()
        {
            StringBuilder script = new StringBuilder();
            script.Append("function CheckBoxClick(obj,id,clientId,inputId,paths){");
            script.Append("var checked=$(obj).attr(\"checked\");");
            script.Append("$(\"#\" + id + \" input[type=checkbox]\").attr(\"checked\",checked);");
            script.Append("if(checked && paths){");
            script.Append("var path=paths.split('/');");
            script.Append("for(i=0;i<path.length;i++)$(\"#\" + clientId + \" input[value=\" + path[i] + \"]\").attr(\"checked\",checked);");
            script.Append("}");
            script.Append("var inputControl=$(\"#\" + clientId + \" input:checked\");");
            script.Append("var str=new String();");
            script.Append("for(i=0;i<inputControl.length;i++)str=str + \"|\" + $(inputControl[i]).val();");
            script.Append("$(\"#\" + inputId).val(str)");
            script.Append("}");
            return script.ToString();
        }

        private string GetChildItemContentId(string value)
        {
            return this.ClientID + "_" + value + "_child";
        }


        public string TextField { get; set; }
        public string ValueField { get; set; }
        public string PathField { get; set; }

        private string selectValues;
        public string SelectValues
        {
            get
            {
                string values = Page.Request.Form[HiddenInputId];
                if (!string.IsNullOrEmpty(values))
                    selectValues =values;
                return selectValues.TrimStart('|').TrimEnd('|');
            }
            set
            {
                selectValues = value;
            }
        }


        public string Style { get; set; }

        public string Css { get; set; }

        public string ItemStyle { get; set; }

        public string ItemCss { get; set; }

        public string ItemHeadStyle { get; set; }

        public string ItemHeadCss { get; set; }

        public string ItemContentCss { get; set; }

        public string ItemContentStyle { get; set; }

        private string HiddenInputId
        {
            get { return this.ClientID + "_Value"; }
        }

    }
}
